package authorization_code_postgres

import (
	"context"
	"errors"
	"fmt"
	"time"

	"github.com/go-oauth2/oauth2/v4"
	"gorm.io/gorm"
)

// 自定义存储实现
// ClientStore Gorm实现的客户端存储
type ClientStore struct {
	db *gorm.DB
}

func NewClientStore(db *gorm.DB) *ClientStore {
	return &ClientStore{db: db}
}

/*
	ClientInfo interface {
		GetID() string
		GetSecret() string
		GetDomain() string
		IsPublic() bool
		GetUserID() string
	}
*/
// GetByID 根据ID获取客户端
func (s *ClientStore) GetByID(ctx context.Context, id string) (oauth2.ClientInfo, error) {
	var c Client
	if err := s.db.Debug().Where("id = ?", id).First(&c).Error; err != nil {
		return nil, err
	}
	return &c, nil
}

//=========

// TokenStore Gorm实现的令牌存储
type TokenStore struct {
	db *gorm.DB
}

func NewTokenStore(db *gorm.DB) *TokenStore {
	return &TokenStore{db: db}
}

// Create 创建令牌
func (s *TokenStore) Create(ctx context.Context, info oauth2.TokenInfo) error {
	fmt.Println("info", info.(*Token))
	token := info.(*Token)
	token, ok := info.(*Token)
	if !ok {
		return errors.New("Create Info is not a *Token")
	}
	return s.db.Create(token).Error
}

// GetByCode 根据授权码获取令牌
func (s *TokenStore) GetByCode(ctx context.Context, code string) (oauth2.TokenInfo, error) {
	var token Token
	if err := s.db.Where("code = ?", code).First(&token).Error; err != nil {
		return nil, err
	}
	if token.CodeExpiresIn.Before(time.Now()) {
		return nil, errors.New("code has expired")
	}
	return &token, nil
}

// GetByAccess 根据访问令牌获取令牌
func (s *TokenStore) GetByAccess(ctx context.Context, access string) (oauth2.TokenInfo, error) {
	var token Token
	if err := s.db.Where("access = ?", access).First(&token).Error; err != nil {
		return nil, err
	}
	if token.AccessExpiresIn.Before(time.Now()) {
		return nil, errors.New("access token has expired")
	}
	return &token, nil
}

// GetByRefresh 根据刷新令牌获取令牌
func (s *TokenStore) GetByRefresh(ctx context.Context, refresh string) (oauth2.TokenInfo, error) {
	var token Token
	if err := s.db.Where("refresh = ?", refresh).First(&token).Error; err != nil {
		return nil, err
	}
	if token.RefreshExpiresIn.Before(time.Now()) {
		return nil, errors.New("refresh token has expired")
	}
	return &token, nil
}

// RemoveByCode 移除授权码
func (s *TokenStore) RemoveByCode(ctx context.Context, code string) error {
	return s.db.Where("code = ?", code).Delete(&Token{}).Error
}

// RemoveByAccess 移除访问令牌
func (s *TokenStore) RemoveByAccess(ctx context.Context, access string) error {
	return s.db.Where("access = ?", access).Delete(&Token{}).Error
}

// RemoveByRefresh 移除刷新令牌
func (s *TokenStore) RemoveByRefresh(ctx context.Context, refresh string) error {
	return s.db.Where("refresh = ?", refresh).Delete(&Token{}).Error
}
